package com.cat.orm.core.db.dao;

import com.cat.orm.core.base.BasePo;
import com.cat.orm.core.base.IBaseData;
import com.cat.orm.core.convert.PersistenceDataConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.Collection;
import java.util.List;

/**
 * 带有转换器的DAO
 * @param <D> 待存储数据
 * @param <P> 转换POJO数据
 */
public class ConvertDao<D extends IBaseData, P extends BasePo> implements IDao<D>{

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 通用的Dao
     */
    protected IDao<P> dao;
    /**
     * 转换器
     */
    protected PersistenceDataConverter<D, P> converter;

    public ConvertDao(Class<P> clazz, JdbcTemplate jdbcTemplate, PersistenceDataConverter<D, P> converter) {
        if (converter == null) {
            throw new IllegalArgumentException("converter is null.");
        }
        this.converter = converter;
        this.dao = new CommonDao<>(clazz, jdbcTemplate);
    }

    public ConvertDao(Class<P> clazz, JdbcTemplate jdbcTemplate, PersistenceDataConverter<D, P> converter, String tableName) {
        if (converter == null) {
            throw new IllegalArgumentException("converter is null.");
        }
        this.converter = converter;
        this.dao = new CommonDao<>(clazz, jdbcTemplate, tableName);
    }

    public ConvertDao(IDao<P> dao, PersistenceDataConverter<D, P> converter) {
        if (dao == null) {
            throw new IllegalArgumentException("dao is null.");
        }
        if (converter == null) {
            throw new IllegalArgumentException("converter is null.");
        }
        this.converter = converter;
        this.dao = dao;
    }

    @Override
    public D selectByKey(Object value) throws Exception{
        P obj = dao.selectByKey(value);
        return this.converter.po2Data(obj);
    }

    @Override
    public Collection<D> selectAll() throws Exception {
        Collection<P> all = dao.selectAll();
        return this.converter.pos2DataList(all);
    }

    @Override
    public Collection<D> selectByIndex(Object[] values) throws Exception {
        Collection<P> clos = dao.selectByIndex(values);
        return this.converter.pos2DataList(clos);
    }

    @Override
    public Collection<D> selectByIndex(String[] props, Object[] values) throws Exception {
        Collection<P> clos = dao.selectByIndex(props, values);
        return this.converter.pos2DataList(clos);
    }

    @Override
    public int insert(D d) {
        P pojo = this.converter.data2Po(d);
        return this.dao.insert(pojo);
    }

    @Override
    public int replace(D d) {
        P pojo = this.converter.data2Po(d);
        return this.dao.replace(pojo);
    }

    @Override
    public int update(D d) {
        P pojo = this.converter.data2Po(d);
        return this.dao.update(pojo);
    }

    @Override
    public int delete(D d) {
        P pojo = this.converter.data2Po(d);
        return this.dao.delete(pojo);
    }

    @Override
    public int deleteAll() {
        return this.dao.deleteAll();
    }

    @Override
    public int[] insertBatch(Collection<D> ds) {
        List<P> pojos = this.converter.dataList2Pos(ds);
        return this.dao.insertBatch(pojos);
    }

    @Override
    public int[] deleteBatch(Collection<D> ds) {
        List<P> pojos = this.converter.dataList2Pos(ds);
        return this.dao.deleteBatch(pojos);
    }

    @Override
    public int[] updateBatch(Collection<D> ds) {
        List<P> pojos = this.converter.dataList2Pos(ds);
        return this.dao.updateBatch(pojos);
    }

    /**
     * 直接操作数据库的sql, 对应的映射应该是表字段
     * @param sql 外部提供的sql语句
     * @return 结果集
     */
    @Override
    public Collection<D> selectBySql(String sql) throws Exception {
        Collection<P> pojos = this.dao.selectBySql(sql);
        return this.converter.pos2DataList(pojos);
    }

    /**
     * 执行的sql
     * @param sql 外部执行的sql语句
     */
    @Override
    public void execute(String sql) {
        this.dao.execute(sql);
    }


}
